home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
haeberli
/
libgutil
/
movie.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
5KB
|
224 lines
/*
* Copyright 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* movie -
* File support for movie files
*
* Paul Haeberli - 1992
*
* exports
*
void sizeofmovie(inf,xsize,ysize,nframes)
int readframe(inf,cbuf,maxsize)
void writemovieheader(outf,ixsize,iysize,nframes)
void writeframe(outf,cbuf,nbytes)
void createmovie(outf,ixsize,iysize,bitsperpix)
void addframe(outf,lbuf,ixsize,iysize)
statmovie(inf)
*
*/
#include "stdio.h"
#include "movie.h"
/*
* support for reading movie files
*/
void sizeofmovie(inf,xsize,ysize,nframes)
FILE *inf;
int *xsize, *ysize, *nframes;
{
int magic;
res_fseek(inf,0,0);
res_fread(&magic,sizeof(int),1,inf);
if(magic != MOVMAGIC) {
fprintf(stderr,"expmov: bad magic in input file %x\n",magic);
exit(1);
}
res_fread(nframes,sizeof(int),1,inf);
res_fread(xsize,sizeof(int),1,inf);
res_fread(ysize,sizeof(int),1,inf);
}
int readframe(inf,cbuf,maxsize)
FILE *inf;
unsigned char *cbuf;
int maxsize;
{
int nbytes;
res_fread(&nbytes,sizeof(int),1,inf);
if(nbytes>maxsize) {
fprintf(stderr,"readframe %d more than max %s\n",nbytes,maxsize);
return;
}
res_fread(cbuf,nbytes,1,inf);
return nbytes;
}
/*
* support for writing movie files
*/
void writemovieheader(outf,ixsize,iysize,nframes)
FILE *outf;
int ixsize, iysize, nframes;
{
int pos, magic;
int xtiles, ytiles;
int xsize, ysize;
xtiles = ixsize/4;
ytiles = iysize/4;
xsize = xtiles*4;
ysize = ytiles*4;
pos = ftell(outf);
fseek(outf,0,0);
magic = MOVMAGIC;
fwrite(&magic,sizeof(int),1,outf);
fwrite(&nframes,sizeof(int),1,outf);
fwrite(&xsize,sizeof(int),1,outf);
fwrite(&ysize,sizeof(int),1,outf);
if(pos<(4*sizeof(int)))
pos = 4*sizeof(int);
fseek(outf,pos,0);
fflush(outf);
}
void writeframe(outf,cbuf,nbytes)
FILE *outf;
unsigned char *cbuf;
int nbytes;
{
fwrite(&nbytes,sizeof(int),1,outf);
fwrite(cbuf,nbytes,1,outf);
fflush(outf);
}
static float p = 1.0;
static float step = 1.0;
static int mxsize, mysize;
static float mbitsperpix;
static int mframeno;
void createmovie(outf,ixsize,iysize,bitsperpix)
FILE *outf;
int ixsize, iysize;
float bitsperpix;
{
mxsize = ixsize;
mysize = iysize;
mbitsperpix = bitsperpix;
mframeno = 0;
writemovieheader(outf,mxsize,mysize,0);
}
#define MAXTHRESH_FLAT (12) /* make bigger for more flat 4x4 areas */
#define THRESH_CHROMA (15) /* controls bw/color for flat 4x4s */
#define THRESH_FLAT (1) /* make bigger for more flat 4x4 areas */
#define THRESH_EDGE (2) /* make smaller for more detail */
static int sthc, sthf, sthe, paramset;
movieparams(thc,thf,the)
int thc, thf, the;
{
sthc = thc;
sthf = thf;
sthe = the;
paramset = 1;
}
void addframe(outf,lbuf,ixsize,iysize)
FILE *outf;
unsigned long *lbuf;
int ixsize, iysize;
{
int cbuflen, wbuflen;
unsigned char *cbuf;
int thc, thf, the;
int maxbytes;
if(ixsize != mxsize || iysize != mysize) {
fprintf(stderr,"addframe: all images must be same size\n");
return;
}
cbuflen = ixsize*iysize;
cbuf = (unsigned char *)malloc(cbuflen*sizeof(char));
step = 1.0;
if(paramset) {
thc = sthc;
thf = sthf;
the = sthe;
wbuflen = compress(lbuf,ixsize,iysize,cbuf,cbuflen,thc,thf,the);
} else {
maxbytes = (ixsize*iysize*mbitsperpix)/8;
while(1) {
thc = THRESH_CHROMA;
thf = p*THRESH_FLAT;
if(thf>MAXTHRESH_FLAT)
thf = MAXTHRESH_FLAT;
the = p*THRESH_EDGE;
wbuflen = compress(lbuf,ixsize,iysize,cbuf,cbuflen,thc,thf,the);
if(wbuflen<=maxbytes) {
#define DEBUG
#ifdef DEBUG
printf("used chroma %d flat %d edge %d P is %f\n", thc, thf, the,p);
#endif
step = 0.5;
p = p-step;
if(p<0.0)
p = 0.0;
break;
}
p = p+step;
}
}
writeframe(outf,cbuf,wbuflen);
mframeno++;
writemovieheader(outf,ixsize,iysize,mframeno);
free(cbuf);
}
/*
* print info about a movie file
*/
void statmovie(inf)
FILE *inf;
{
int xsize, ysize, nframes;
int nbytes, npix, bypf, pos;
float bpp;
pos = ftell(inf);
sizeofmovie(inf,&xsize,&ysize,&nframes);
fseek(inf,pos,0);
nbytes = sizeoffile(inf);
npix = xsize*ysize*nframes;
bpp = (nbytes*8.0)/npix;
bypf = nbytes/nframes;
fprintf(stderr,"movie size %d by %d pixels, %d frames\n",xsize,ysize,nframes);
fprintf(stderr,"frames per second: %d\n",10);
if(nframes>0) {
fprintf(stderr,"average bits per pixel: %f\n",bpp);
fprintf(stderr,"average bytes per frame: %d\n",bypf);
fprintf(stderr,"average bytes per second: %d\n",10*bypf);
}
}